﻿using System;
using CID.Domain.Exceptions;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Tests.Infrastructure
{
    [TestFixture]
    class ParameterTests : BaseFunctionalTests
    {
        private const string Name = "Parameter Name";
        private const string AlternateName = "Alternate Name";
        private const string Description = "Parameter Description";
        private const ParameterType Type = ParameterType.Boolean;
        private static readonly ITemplate Template = StubsBuilder.BuildActivationTemplateStub();

        private Parameter parameter = null;

        public override void  SetUp()
        {
 	        base.SetUp();
            parameter = new Parameter(Name, Description, Type, Template);
        }

        #region Constructor
        [Test]
        public void CreateNewParameter_TypeShouldBeDefaultedToString()
        {
            var parameter = new Parameter(Name, Description, Type, Template);

            Assert.AreEqual(Name, parameter.Name);
            Assert.AreEqual(Description, parameter.Description);
            Assert.AreEqual(Type, parameter.Type);
            Assert.AreEqual(Template, parameter.Template);
        }

        [Test, ExpectedException(typeof(InvalidParameterNameException))]
        public void CreateNewParameter_ReservedName_ShouldThrowException()
        {
            parameter = new Parameter(Parameter.ReservedNames.ComponentName, Description, Type, Template);
        }
        #endregion

        #region RemoveFromTeplate
        [Test]
        public void RemoveFromTemplateOnce_TemplateShouldBeSetToNull()
        {
            parameter.RemoveFromTemplate();

            Assert.IsNull(parameter.Template);
        }

        [Test]
        public void RemoveFromTemplateTwice_TemplateShouldBeSetToNull()
        {
            parameter.RemoveFromTemplate();
            parameter.RemoveFromTemplate();

            Assert.IsNull(parameter.Template);
        }
        #endregion

        #region Name
        [Test]
        public void SetParameterName_ValidName_ShouldSucceed()
        {
            parameter.Name = AlternateName;

            Assert.AreEqual(AlternateName, parameter.Name);
        }

        [Test, ExpectedException(typeof(InvalidParameterNameException))]
        public void SetParameterName_ReservedName_ShouldThrowException()
        {
            parameter.Name = Parameter.ReservedNames.ComponentName;
        }
        #endregion

        #region ReservedNames
        [Test]
        public void IsReserved_EveryIndividualMember_ShouldReturnTrue()
        {
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.ComponentName));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.VersionName));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.PackageComment));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.PackagePath));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.ReleaseName));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.TargetServerAddress));
            Assert.IsTrue(Parameter.ReservedNames.IsReserved(Parameter.ReservedNames.TargetServersAddresses));
        }

        [Test]
        public void IsReserved_EveryMemberInAll_ShouldReturnTrue()
        {
            foreach (var reservedName in Parameter.ReservedNames.All)
                Assert.IsTrue(Parameter.ReservedNames.IsReserved(reservedName));
        }

        [Test]
        public void IsReserved_RandomValue_ShouldReturnFalse()
        {
             Assert.IsFalse(Parameter.ReservedNames.IsReserved(Guid.NewGuid().ToString()));
        }
        #endregion
    }
}
